home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / pcmagazi / 1986 / 07 / rendir.asm next >
Assembly Source File  |  1986-01-23  |  10KB  |  245 lines

  1. RENDIR segment para public 'code'
  2.     assume    cs:RENDIR, ds:RENDIR, es:RENDIR, ss:NOTHING
  3.     org    100h        ; .COM format
  4. BEGIN:
  5.     jmp    CODE_START    ; Jump around data declarations
  6. DECLARE:    ; Equates and Storage allocation for messages & data areas
  7.     COPYRIGHT    db    'RENDIR (C) 1986, Ziff-Davis Publishing Co.'
  8.             db    13,10,'$'
  9.     PATH_FILE_LEN    equ    77  ;Length = 1, Path = 63, FileName = 12, 0 = 1
  10.     SOURCE_NAME    db    PATH_FILE_LEN dup (0)
  11.     TARGET_NAME    db    PATH_FILE_LEN dup (0)
  12.     TARGET_END    dw    $ - 1
  13.     VALID_IN    db    '/abcdefghijklmnopqrstuvwxyz,;=',9
  14.     VALID_OUT    db    '\ABCDEFGHIJKLMNOPQRSTUVWXYZ',4 dup(32)
  15.     VALID_NUM    equ    $ - VALID_OUT + 1
  16.     ERR_HEAD    db    10,13,'RENDIR Error - $'
  17.     BAD_VERSION    db    'Must be PC-DOS 3.0 or Higher$'
  18.     NO_PARMS    db    'Correct Syntax is:',13,10,10
  19.             db    'RENDIR [D:][Source_Path]Source_Name[.Ext] '
  20.             db    'Target_Name[.Ext]$'
  21.     NO_TARGET    db    'No Target Name Specified$'
  22.     BAD_TARGET    db    'Invalid "\" or ":" in Target Name$'
  23.     DIR_NOT_FOUND    db    'Source Directory Not Found$'
  24.     NOT_DIRECTORY    db    'Source File Not a Directory$'
  25.     PATH_NOT_FOUND    db    'Source or Target Path Not Found$'
  26.     ACCESS_DENIED    db    'Access to Target Denied or Target Exists$'
  27.     PC_DOS_2_PATCH    db    13,10,'or $'
  28.     DRIVES_CONFLICT db    'Source and Target Disk Drives Conflict$'
  29.     UNDEFINED_ERR    db    'Undefined Error: PC-DOS Function 56H$'
  30.     ERR_TAIL    db    10,10,13,' . . . Aborting',10,13,13,'$'
  31.     GOOD_MSG1    db    10,13,'Directory "$'
  32.     GOOD_MSG2    db    '" . . renamed to . . "$'
  33.     GOOD_MSG3    db    '"$'
  34.     END_LINE    db    10,13,'$'
  35. CODE_START:    ; Processing logic starts here
  36.     mov    dx,offset COPYRIGHT    ; Display copyright notice
  37.     mov    ah,9h            ; Request display string
  38.     int    21h            ; Call PC-DOS
  39.     mov    ah,30h            ; Request PC-DOS version
  40.     int    21h            ; Call PC-DOS
  41.     cmp    al,3            ; Must be 3.0 or higher
  42.     jae    VERSION_OK        ; If it is, keep going
  43.     mov    dx,offset BAD_VERSION    ; Otherwise, exit with error
  44.     jmp    ERROR_EXIT
  45. VERSION_OK:    ; Parse command line into source name and target name
  46.     mov    si,80h            ; PSP parameter byte count pointer
  47.     mov    cl,[si]         ; Move byte count to CL
  48.     xor    ch,ch            ; Zero CH
  49.     jcxz    PARMS_NO_GOOD        ; If CX is zero, there are no parameters
  50.     mov    dx,cx            ; Save byte count in dx
  51.     inc    si            ; Point to parameter area
  52.     mov    di,si            ; Copy SI to DI for cleanup routine
  53.     cld                ; Set direction flag to forward
  54. CLEAN_PARMS:    ; Change valid delimiters to blanks, lower to upper case
  55.     lodsb                ; Load each character to AL
  56.     push    di            ; Save DI on stack
  57.     mov    di,offset VALID_IN    ; Point to table of valid inputs
  58.     push    cx            ; Save CX on stack
  59.     mov    cx,VALID_NUM        ; Set CX to number of inputs to look for
  60. repne    scasb                ; See if any are in AL
  61.     jcxz    CLEAN_END        ; If not, change nothing
  62.     mov    bx,VALID_NUM        ; Set up BX to point to valid output
  63.     sub    bx,cx            ; This will leave BX one off
  64.     mov    al,VALID_OUT [bx - 1]    ; Load the valid output to AL
  65. CLEAN_END:
  66.     pop    cx            ; Restore CX
  67.     pop    di            ; Restore DI
  68.     stosb                ; Store modified AL back to PSP
  69. loop    CLEAN_PARMS            ; Loop until CX is zero
  70.     mov    cx,dx            ; Restore number of bytes in PSP to CX
  71.     mov    dx,2            ; Set DX to look for up to 2 parameters
  72.     mov    bx,offset SOURCE_NAME    ; Set BX to address of 1st parameter
  73.     mov    al,' '                  ; Set up to scan for first non-blank
  74.     mov    di,81h            ; Set DI to PC-DOS parameter pointer
  75. FIND_PARMS:    ; Start looking for parameters, load to program storage
  76. repe    scasb                ; Scan while blanks
  77.     mov    si,di            ; Set SI to second non-blank byte
  78.     dec    si            ; Adjust it to first non-blank byte
  79.     inc    cx            ; Adjust CX to compensate
  80.     jcxz    PARMS_LOADED        ; If CX is zero, no parameters left
  81.     mov    di,bx            ; Set DI to parameter hold area
  82.     mov    ax,cx            ; Store CX to first byte of hold area
  83.     stosb                ; DI is adjusted to second byte here
  84. STORE:    lodsb                ; Load each byte to AL
  85.     cmp    al,' '                  ; Is it a blank?
  86.     jz    END_STORE        ; Yes, end of this parameter
  87.     stosb                ; No, store the byte to hold area
  88. END_STORE:
  89.     loopnz    STORE            ; Keep looking
  90.     sub    [bx],cx         ; Store number of bytes in each
  91.     jcxz    PARMS_LOADED        ; If CX is zero, no more parameters
  92.     dec    byte ptr [bx]        ; parameter to first byte of hold area
  93.     mov    di,si            ; Set up to scan for next non-blank
  94.     dec    di            ; Adjust DI to point to the blank
  95.     inc    cx            ; Adjust CX to compensate
  96.     dec    dx            ; Decrement DX counter
  97.     cmp    dx,0            ; Is DX zero?
  98.     jz    PARMS_LOADED        ; Yes, all expected parameters loaded
  99.     add    bx,PATH_FILE_LEN    ; No, point to next part of hold area
  100.     jmp    FIND_PARMS        ; Go back and look for more
  101. PARMS_LOADED:                ; All parameters are loaded
  102.     cmp    SOURCE_NAME[0],0    ; If there are no bytes in the
  103.     je    PARMS_NO_GOOD        ; SOURCE_NAME, no parameters present
  104.     cmp    TARGET_NAME[0],0    ; Same for TARGET_NAME
  105.     ja    CHECK_PARMS
  106. PARMS_NO_GOOD:                ; Exit with an error if there
  107.     mov    dx,offset NO_PARMS    ; are no or incorrect parameters passed
  108.     jmp    ERROR_EXIT
  109. CHECK_PARMS:                ; Check for '\' or ':' in target name
  110.     mov    di,TARGET_END        ; Point DI to end of parameter area
  111.     mov    si,offset TARGET_NAME    ; Point SI to number of bytes area
  112.     lodsb                ; Load number of bytes to AL
  113.     xor    ah,ah            ; Zero AH
  114.     mov    cx,ax            ; Move to CX for loop
  115.     push    cx            ; Save CX on stack
  116.     add    si,cx            ; Adjust SI to end of target name
  117.     dec    si            ;
  118.     std                ; Set direction flag to reverse
  119. MOVE_TARGET:                ; Move target to end of area while
  120.     lodsb                ; checking for '\'
  121.     cmp    al,'\'
  122.     je    BAD_TARGET_FOUND    ; If found, target is bad
  123.     cmp    al,':'
  124.     je    BAD_TARGET_FOUND
  125.     stosb                ; Store byte to end of area
  126.     loop    MOVE_TARGET        ; Keep looking
  127.     add    di,1            ; Adjust DI
  128.     push    di            ; Save DI on stack
  129.     jmp    FIND_SOURCE_DIR     ; Go process source name
  130. BAD_TARGET_FOUND:            ; Exit with error if target
  131.     mov    dx,offset BAD_TARGET    ; contains a '\'
  132.     jmp    ERROR_EXIT
  133. FIND_SOURCE_DIR:            ; Look for end of path name in source
  134.     mov    si,offset SOURCE_NAME    ; Point SI to number of bytes
  135.     lodsb                ; Load number of bytes to AL
  136.     xor    ah,ah            ; Zero AH
  137.     mov    di,si            ; Move SI to DI for scan
  138.     mov    cx,ax            ; Move AX to CX for scan repeat
  139.     add    di,cx            ; Adjust DI to end of source name
  140.     dec    di            ;
  141.     mov    al,'\'                  ; Scan for '\'
  142. repnz    scasb
  143.     cld                ; Set direction flag to forward
  144.     jnz    NO_DIR            ; Directory is in current directory
  145.     dec    cx            ; Adjust CX
  146.     mov    di,offset TARGET_NAME + 1    ; Point DI to target name
  147.     mov    si,offset SOURCE_NAME + 1    ; Point SI to source name
  148. rep    movsb                ; Move path name to target name
  149.     jmp    MOVE_NAME        ; DI points to position for target name
  150. NO_DIR:                 ; No path, point to beginning of name
  151.     cmp    SOURCE_NAME[2],':'      ; Check for disk drive specification
  152.     jne    NO_DISK
  153.     mov    di,offset TARGET_NAME + 1    ; Point DI to target name
  154.     mov    si,offset SOURCE_NAME + 1    ; Point SI to source name
  155.     mov    cx,2            ; Move the two bytes into target name
  156. rep    movsb                ; that contain disk drive specification
  157.     jmp    MOVE_NAME
  158. NO_DISK:
  159.     mov    di,offset TARGET_NAME + 1
  160. MOVE_NAME:                ; Move target name to correct position
  161.     pop    si            ; Restore saved DI in SI
  162.     pop    cx            ; Restore CX
  163. rep    movsb
  164.     mov    al,0            ; Finish ASCIIZ string with a binary 0
  165.     stosb
  166. FIND_DIRECTORY:             ; Does source directory exist?
  167.     mov    dx,offset SOURCE_NAME+1 ; DX points to SOURCE_NAME
  168.     mov    ah,4eh            ; Request find file
  169.     mov    cx,10h            ; Set attribute for directories
  170.     int    21h            ; Call PC-DOS
  171.     jnc    FOUND_FILE        ; If no error, a file was found
  172.     jmp    NO_DIRECTORY
  173. FOUND_FILE:
  174.     mov    si,95h            ; Position of attribute byte in DTA
  175.     lodsb                ; Load attribute byte to AL
  176.     and    al,10h            ; Check to see if it's a directory
  177.     jnz    RENAME_DIRECTORY    ; If not zero, it's a directory
  178.     mov    dx,offset NOT_DIRECTORY
  179.     jmp    ERROR_EXIT
  180. NO_DIRECTORY:                ; Exit with error if no directory
  181.     mov    dx,offset DIR_NOT_FOUND ; If file not found, exit
  182.     jmp    ERROR_EXIT        ; program with error message
  183. RENAME_DIRECTORY:
  184.     mov    dx,offset SOURCE_NAME + 1    ; DX points to old file name
  185.     mov    di,offset TARGET_NAME + 1    ; DI points to new file name
  186.     mov    ah,56h            ; Request rename file
  187.     int    21h            ; Call PC-DOS
  188.     jnc    GOOD_RENDIR        ; If no error, call was successful
  189.     cmp    ax,3            ; Check for error 3 (path not found)
  190.     jne    ERR_5
  191.     mov    dx,offset PATH_NOT_FOUND
  192.     jmp    ERROR_EXIT        ; Exit program with error message
  193. ERR_5:    cmp    ax,5            ; Check for error 5 (file inaccessible)
  194.     jne    ERR_17
  195.     mov    dx,offset ACCESS_DENIED
  196.     jmp    ERROR_EXIT
  197. ERR_17: cmp    ax,17            ; Check for error 17 (drive conflict)
  198.     jne    UNDEF
  199.     mov    dx,offset DRIVES_CONFLICT
  200.     jmp    ERROR_EXIT        ; Exit program with error message
  201. UNDEF:    mov    dx,offset UNDEFINED_ERR ; Undefined error from function 56H
  202.     jmp    ERROR_EXIT        ; Exit program with error message
  203. GOOD_RENDIR:                ; Exit with message
  204.  
  205.     mov    ah,9h            ; Request display string
  206.     mov    dx,offset GOOD_MSG1    ; Display GOOD_MSG1
  207.     int    21h            ; Call PC-DOS
  208.     mov    cx,2            ; 2 fields - source & target file
  209.     mov    bx,offset SOURCE_NAME + 1    ; Point to source file
  210. START1: mov    si,bx            ; Copy BX to SI
  211. START2: lodsb                ; Load each byte to AL
  212.     cmp    al,0            ; If ASCII 0, end of field
  213.     je    BETWEEN
  214.     mov    dl,al            ; Copy byte to DL for funciton 2H
  215.     mov    ah,2h            ; Request display one byte
  216.     int    21h            ; Call PC-DOS
  217.     jmp    START2            ; Get next character
  218. BETWEEN:cmp    cx,2            ; Is it first or second field?
  219.     jne    CR_LF            ; If second, display end of message
  220.     mov    ah,9h            ; Request display string
  221.     mov    dx,offset GOOD_MSG2    ; Display GOOD_MSG2
  222.     int    21h            ; Call PC-DOS
  223.     jmp    NEXT            ; Go process next field
  224. CR_LF:    mov    ah,9h            ; Request display string
  225.     mov    dx,offset GOOD_MSG3    ; Display GOOD_MSG3
  226.     int    21h            ; Call PC-DOS
  227.     mov    dx,offset END_LINE    ; Terminate display line
  228.     mov    ah,9h            ; Request display string
  229.     int    21h            ; Call PC-DOS
  230. NEXT:    add    bx,PATH_FILE_LEN    ; Move BX to point to next field
  231.     loop    START1            ; Loop for second field
  232.     jmp    EXIT            ; Exit RENDIR
  233. ERROR_EXIT:                ; Print Error Message and Exit
  234.     push    dx            ; Save error message pointer on stack
  235.     mov    ah,9h            ; Request display string
  236.     mov    dx,offset ERR_HEAD    ; Display error header
  237.     int    21h            ; Call PC-DOS
  238.     pop    dx            ; Display error message
  239.     int    21h            ; Call PC-DOS
  240.     mov    dx,offset ERR_TAIL    ; Display error tail
  241.     int    21h            ; Call PC-DOS
  242. EXIT:    int    20h            ; Exit to PC-DOS
  243. RENDIR    ends
  244.     end    BEGIN
  245.